package lcd

import (
	"fmt"
	"os"
	"strings"
	"sync"
)

const (
	sysfsPathBase   = "/sys/devices/platform/tm1629a"
	syfsBrightness  = sysfsPathBase + "/brightness"
	syfsDisplayOn   = sysfsPathBase + "/display_on"
	syfsDisplayText = sysfsPathBase + "/display_text"
	syfsNumDigits   = sysfsPathBase + "/num_digits"
	syfsLedType     = sysfsPathBase + "/led_type"
	syfsAddrMode    = sysfsPathBase + "/addr_mode"
	syfsSegments    = sysfsPathBase + "/segments"
)

// 段码定义
const (
	SegA = 1 << iota
	SegB
	SegC
	SegD
	SegE
	SegF
	SegG
	SegDP
)

// 数字0-9的段码表
var digitSegments = []byte{
	SegA | SegB | SegC | SegD | SegE | SegF,        // 0
	SegB | SegC,                                    // 1
	SegA | SegB | SegD | SegE | SegG,               // 2
	SegA | SegB | SegC | SegD | SegG,               // 3
	SegB | SegC | SegF | SegG,                      // 4
	SegA | SegC | SegD | SegF | SegG,               // 5
	SegA | SegC | SegD | SegE | SegF | SegG,        // 6
	SegA | SegB | SegC,                             // 7
	SegA | SegB | SegC | SegD | SegE | SegF | SegG, // 8
	SegA | SegB | SegC | SegD | SegF | SegG,        // 9
}

// 字母的段码表
var letterSegments = map[rune]byte{
	'A': SegA | SegB | SegC | SegE | SegF | SegG,
	'B': SegC | SegD | SegE | SegF | SegG,
	'C': SegA | SegD | SegE | SegF,
	'D': SegB | SegC | SegD | SegE | SegG,
	'E': SegA | SegD | SegE | SegF | SegG,
	'F': SegA | SegE | SegF | SegG,
	'H': SegB | SegC | SegE | SegF | SegG,
	'I': SegB | SegC,
	'L': SegD | SegE | SegF,
	'N': SegA | SegB | SegC | SegE | SegF,
	'O': SegA | SegB | SegC | SegD | SegE | SegF,
	'P': SegA | SegB | SegE | SegF | SegG,
	'S': SegA | SegC | SegD | SegF | SegG,
	'T': SegD | SegE | SegF | SegG,
	'U': SegB | SegC | SegD | SegE | SegF,
	'V': SegB | SegC | SegD | SegE | SegF,
	'-': SegG,
	'_': SegD,
	' ': 0,
}

// Display 显示驱动
type Display struct {
	mu sync.Mutex
}

// NewDisplay 创建新的显示驱动
func NewDisplay() (*Display, error) {
	d := &Display{}
	if err := d.init(); err != nil {
		return nil, err
	}
	return d, nil
}

// init 初始化显示设备
func (d *Display) init() error {
	// 设置显示位数为4
	if err := d.writeToSysfs(syfsNumDigits, "4"); err != nil {
		return fmt.Errorf("设置显示位数失败: %w", err)
	}

	// 设置亮度为最大
	if err := d.writeToSysfs(syfsBrightness, "7"); err != nil {
		return fmt.Errorf("设置亮度失败: %w", err)
	}

	// 打开显示
	if err := d.writeToSysfs(syfsDisplayOn, "1"); err != nil {
		return fmt.Errorf("打开显示失败: %w", err)
	}

	return nil
}

// writeToSysfs 向sysfs文件写入数据
func (d *Display) writeToSysfs(path, data string) error {
	d.mu.Lock()
	defer d.mu.Unlock()

	f, err := os.OpenFile(path, os.O_WRONLY, 0644)
	if err != nil {
		return fmt.Errorf("打开sysfs文件[%s]失败: %w", path, err)
	}
	defer f.Close()

	if _, err := f.WriteString(data); err != nil {
		return fmt.Errorf("写入sysfs文件[%s]失败: %w", path, err)
	}

	return nil
}

// ShowText 显示文本
func (d *Display) ShowText(text string, dot bool) error {
	segments := make([]byte, 4)
	text = strings.ToUpper(text)
	runes := []rune(text)

	// 填充段码
	for i := 0; i < 4 && i < len(runes); i++ {
		r := runes[i]
		if r >= '0' && r <= '9' {
			segments[i] = digitSegments[r-'0']
		} else if seg, ok := letterSegments[r]; ok {
			segments[i] = seg
		}
	}

	// 添加小数点
	if dot && len(segments) > 0 {
		segments[0] |= SegDP
	}

	// 构建段码字符串
	var sb strings.Builder
	for i, seg := range segments {
		if i > 0 {
			sb.WriteString(" ")
		}
		sb.WriteString(fmt.Sprintf("%d %02X", i, seg))
	}

	return d.writeToSysfs(syfsSegments, sb.String())
}

// ShowNumber 显示数字
func (d *Display) ShowNumber(num int, dot bool) error {
	// 格式化为4位数字
	text := fmt.Sprintf("%04d", num)
	return d.ShowText(text, dot)
}

// ShowPattern 显示特定段码模式
func (d *Display) ShowPattern(patterns []byte) error {
	var sb strings.Builder
	for i, pat := range patterns {
		if i > 0 {
			sb.WriteString(" ")
		}
		sb.WriteString(fmt.Sprintf("%d %02X", i, pat))
	}
	return d.writeToSysfs(syfsSegments, sb.String())
}

// Clear 清除显示
func (d *Display) Clear() error {
	return d.writeToSysfs(syfsSegments, "0 00 1 00 2 00 3 00")
}

// Close 关闭显示
func (d *Display) Close() error {
	return d.writeToSysfs(syfsDisplayOn, "0")
}
